home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / batchut / rbsetnv1.zip / WILDARGV.C < prev   
Text File  |  1991-01-03  |  6KB  |  359 lines

  1. /*
  2.  *    setargv.c ->    parse arguments
  3.  *
  4.  *    This code evolved out of a requirement for expansion of wild-card
  5.  *    arguments given on the command line.  Turbo C's wildarg.obj
  6.  *    actually produces a reference to __wildargv, which still doesn't
  7.  *    do the job I needed (for example, directory names are not
  8.  *    expanded).
  9.  *
  10.  *    This version both expands wild-card arguments and converts them
  11.  *    to lower case (a cosmetic thing for me).  Arguments that are
  12.  *    quoted (with either " or ') are left alone, but the quote
  13.  *    characters are stripped.  A leading quote may be escaped with
  14.  *    a backslash (\" or \').  Quotes within arguments (ARG="a b c")
  15.  *    are not handled in the Un*x fashion.  If no matching filename
  16.  *    is found, the argument is passed unchanged.
  17.  *
  18.  *    Two conditional-compilation flags are provided:
  19.  *        FIXARG0:    convert argv[0] to lower case and switch
  20.  *                all backslashes to slashes (cosmetic)
  21.  *        SORTARGS:    use qsort() to sort the expansions of
  22.  *                each argument
  23.  *
  24.  *    Further enhancements greatly appreciated.
  25.  *
  26.  *    This code placed in the public domain on October 25, 1989 by
  27.  *    its original author, Frank Whaley.
  28.  *
  29.  *  Added check for '[' and ']'              R. Brittain  4/21/90
  30.  *  for use with wildunix TSR
  31.  */
  32.  
  33. #define    MAXARG    1024    /*  max arguments  */
  34.  
  35. #include <ctype.h>
  36. #include <dir.h>
  37. #include <dos.h>
  38. #include <mem.h>
  39. #include <string.h>
  40. #include <alloc.h>
  41.  
  42.     /*  let's do some things with macros...  */
  43. #define    ISQUOTE(c)    (((c)=='"')||((c)=='\''))
  44. #define    ISBLANK(c)    (((c)==' ')||((c)=='\t'))
  45.  
  46. static char *cl;            /*  -> local copy of command line  */
  47.  
  48.     /*  the following are used by run-time startup (c0?.obj)  */
  49. extern int _argc;            /*  number of args  */
  50. extern char **_argv;        /*  arg ptrs  */
  51.  
  52.     /*  forward declarations  */
  53. static void *allocopy(void *src, int len);
  54. static void getreg(char *av[]);
  55. static void getwild(char *av[]);
  56.  
  57.  
  58. /*
  59.  *    _setargv() ->    set argument vector
  60.  */
  61. void
  62. _setargv()
  63. {
  64.     char buf[128];        /*  working buffer  */
  65.     char far *cline;    /*  generic far ptr  */
  66.     char *av[MAXARG];    /*  working vector  */
  67.     int len;        /*  command line length  */
  68.  
  69.     /*  copy program name from environment  */
  70.     cl = buf;
  71.     cline = MK_FP(*(int far *)MK_FP(_psp, 0x2c), 0);
  72.     while ( *cline )
  73.     {
  74.         if ( !*++cline )
  75.         {
  76.             cline++;
  77.         }
  78.     }
  79.     cline += 3;
  80.     while ( *cline )
  81.     {
  82. #ifdef    FIXARG0
  83.         *cl = tolower(*cline++);
  84.         if ( *cl == '\\' )
  85.         {
  86.             *cl = '/';
  87.         }
  88.         cl++;
  89. #else
  90.         *cl++ = *cline++;
  91. #endif
  92.     }
  93.     *cl = '\0';
  94.     av[0] = allocopy(buf, strlen(buf) + 1);
  95.  
  96.     /*  copy cmd line from PSP  */
  97.     cl = buf;
  98.     cline = MK_FP(_psp, 0x80);
  99.     len = *cline++;
  100.     while ( len )
  101.     {
  102.         *cl++ = *cline++;
  103.         len--;
  104.     }
  105.     *cl = 0;
  106.  
  107.     _argc = 1;
  108.     cl = buf;
  109.     while ( *cl )
  110.     {
  111.         /*  deblank  */
  112.         while ( ISBLANK(*cl) )
  113.         {
  114.             cl++;
  115.         }
  116.  
  117.         /*  pick next argument  */
  118.         while ( *cl && (_argc < MAXARG) )
  119.         {
  120.             if ( iswild() )
  121.             {
  122.                 getwild(av);
  123.             }
  124.             else
  125.             {
  126.                 getreg(av);
  127.             }
  128.  
  129.             /*  deblank  */
  130.             while ( ISBLANK(*cl) )
  131.             {
  132.                 cl++;
  133.             }
  134.         }
  135.     }
  136.  
  137.     /*  copy argument vector  */
  138.     _argv = allocopy(av, _argc * sizeof(char *));
  139. }
  140.  
  141.  
  142. /*
  143.  *    does current argument contain a wildcard ??
  144.  */
  145. static int
  146. iswild()
  147. {
  148.     char *s = cl;
  149.  
  150.     if ( ISQUOTE(*s) )
  151.     {
  152.         return ( 0 );
  153.     }
  154.  
  155.     while ( *s && !ISBLANK(*s) )
  156.     {
  157.         if ( (*s == '\\') && ISQUOTE(*(s + 1)) )
  158.         {
  159.             s += 2;
  160.         }
  161.         else if ( (*s == '?') || (*s == '*') || (*s == '[') || (*s == ']'))
  162.         {
  163.             return ( 1 );
  164.         }
  165.  
  166.         s++;
  167.     }
  168.  
  169.     return ( 0 );
  170. }
  171.  
  172.  
  173. /*
  174.  *    allocopy() ->    allocate space for a copy of something
  175.  */
  176. static void *
  177. allocopy(void *src, int len)
  178. {
  179.     void *copy;
  180.  
  181.     copy = sbrk(len);
  182.     if ( copy == (void *)(-1) )
  183.     {
  184.         write(2, "\nMemory shortage\n", 17);
  185.         exit(1);
  186.     }
  187.     return ( memcpy(copy, src, len) );
  188. }
  189.  
  190.  
  191. /*
  192.  *    getreg() ->    pick a regular argument from command line
  193.  */
  194. static void
  195. getreg(char *av[])
  196. {
  197.     char buf[128];
  198.     char *bp = buf;
  199.     char quote;
  200.  
  201.     /*  copy argument (minus quotes) into local buffer  */
  202.     if ( ISQUOTE(*cl) ) {
  203.         quote = *cl++;
  204.         while ( *cl&& (*cl != quote) )
  205.         {
  206.             *bp++ = *cl++;
  207.         }
  208.     } else    {
  209.         while ( *cl && !ISBLANK(*cl) ) {
  210.             if ( (*cl == '\\') && ISQUOTE(*(cl + 1)) )
  211.             {
  212.                 cl++;
  213.             }
  214.  
  215.             *bp++ = *cl++;
  216.         }
  217.     }
  218.     *bp = '\0';
  219.  
  220.     /*  skip over terminator char  */
  221.     if ( *cl )
  222.     {
  223.         cl++;
  224.     }
  225.  
  226.     /*  store ptr to copy of string  */
  227.     av[_argc++] = allocopy(buf, strlen(buf) + 1);
  228. }
  229.  
  230.  
  231. /*
  232.  *    lwrcat() ->    concatenate strings, conver to lower case
  233.  */
  234. static char *
  235. lwrcat(char *s, char *t)
  236. {
  237.     char *cp = s;
  238.  
  239.     while ( *cp )
  240.     {
  241.         cp++;
  242.     }
  243.     /*  avoid a warning  */
  244.     while ( *t )
  245.     {
  246.         *cp++ = tolower(*t++);
  247.     }
  248.     *cp = '\0';
  249.  
  250.     return ( s );
  251.     }
  252.  
  253.  
  254. /*
  255.  *    pickpath() ->    pick pathname from argument
  256.  */
  257. static void
  258. pickpath(char *arg, char *path)
  259. {
  260.     char *t;
  261.     int n;
  262.  
  263.     /*  find beginning of basename  */
  264.     for ( t = arg + strlen(arg) - 1; t >= arg; t-- )
  265.     {
  266.         if ( (*t == '\\') || (*t == '/') || (*t == ':') )
  267.         {
  268.             break;
  269.         }
  270.     }
  271.  
  272.     /*  pick off path  */
  273.     for ( n = (t - arg) + 1, t = arg; n--; )
  274.     {
  275.         *path = tolower(*t);
  276.         path++;
  277.         t++;
  278.     }
  279.     *path = '\0';
  280. }
  281.  
  282.  
  283. #ifdef    SORTARGS
  284. /*
  285.  *    mycmp() ->    comparison routine for qsort()
  286.  */
  287. static int
  288. mycmp(char **s, char **t)
  289. {
  290.     return ( strcmp(*s, *t) );
  291. }
  292. #endif
  293.  
  294.  
  295. /*
  296.  *    getwild() ->    get wildcard argument from command line
  297.  */
  298. static void
  299. getwild(char *av[])
  300. {
  301.     char path[128];
  302.     char srch[128];
  303.     char *s = srch;
  304.     struct ffblk f;
  305. #ifdef    SORTARGS
  306.     char **firstv = &av[_argc];
  307.     int nmatched = 0;
  308. #endif
  309.  
  310.     /*  pick search string  */
  311.     while ( *cl && !ISBLANK(*cl) )
  312.     {
  313.         *s++ = *cl++;
  314.     }
  315.     *s = '\0';
  316.  
  317.     pickpath(srch, path);
  318.  
  319.     if ( findfirst(srch, &f, 0x17) )
  320.     {
  321.         /*  no match, just copy argument  */
  322.         av[_argc++] = allocopy(srch, strlen(srch) + 1);
  323.         return;
  324.     }
  325.  
  326.     /*  add name if not "." or ".."  */
  327.     if ( f.ff_name[0] != '.' )
  328.     {
  329.         strcpy(srch, path);
  330.         lwrcat(srch, f.ff_name);
  331.         av[_argc++] = allocopy(srch, strlen(srch) + 1);
  332. #ifdef    SORTARGS
  333.         nmatched++;
  334. #endif
  335.     }
  336.  
  337.     /*  find the rest  */
  338.     while ( !findnext(&f) && (_argc < MAXARG) )
  339.     {
  340.         if ( f.ff_name[0] != '.' )
  341.         {
  342.             strcpy(srch, path);
  343.             lwrcat(srch, f.ff_name);
  344.             av[_argc++] = allocopy(srch, strlen(srch) + 1);
  345. #ifdef    SORTARGS
  346.             nmatched++;
  347. #endif
  348.         }
  349.     }
  350.  
  351. #ifdef    SORTARGS
  352.     /*  sort these entries  */
  353.     qsort(firstv, nmatched, sizeof(char *), mycmp);
  354. #endif
  355. }
  356. /*
  357.  *    END of setargv.c
  358.  */
  359.